﻿using HCMS.Extensions;
using HCMS.IServices.Manage;
using HCMS.Utils;
using System.Net;
using System.Net.Http.Headers;
using System.Text;

namespace HCMS.HttpApi.Site.MiddlewareExtensions
{
    /// <summary>
    /// Swagger Basic 认证 中间件
    /// </summary>
    /// <remarks>
    /// 接口文档 需要登录才能查看
    /// </remarks>
    public class SwaggerBasicAuthMiddleware
    {
        private readonly RequestDelegate next;

        public SwaggerBasicAuthMiddleware(RequestDelegate next)
        {
            this.next = next;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            // 必须设置输出内容编码，不然页面中文会乱码
            context.Response.Headers["Content-Type"] = "text/plain;charset=utf-8";

            if (context.Request.Path.StartsWithSegments("/swagger"))
            {
                Action<string> authFailedResponse = delegate (string msg)
                {
                    // 告知客户端需要进行 Basic 认证
                    context.Response.Headers["WWW-Authenticate"] = "Basic";
                    context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                    if (!string.IsNullOrWhiteSpace(msg))
                    {
                        context.Response.WriteAsync(msg);
                    }
                };

                // Basic 认证
                string authHeader = context.Request.Headers["Authorization"].ToString("");
                if (authHeader != null && authHeader.StartsWith("Basic"))
                {
                    var header = AuthenticationHeaderValue.Parse(authHeader);
                    var inBytes = Convert.FromBase64String(header.Parameter ?? "");
                    var credentials = Encoding.UTF8.GetString(inBytes).Split(':');
                    var userName = credentials[0].ToString("");
                    var password = credentials[1].ToString("");

                    if (string.IsNullOrWhiteSpace(userName) || string.IsNullOrWhiteSpace(password))
                    {
                        authFailedResponse("登录失败。请填写正确的 用户名 和 密码");
                        return;
                    }

                    // 使用【管理系统】管理员 账户校验
                    var adminAppService = context.RequestServices.GetRequiredService<IAdminAppService>();

                    var admin = await adminAppService.BaseFirstOrDefaultAsync(t => t.AdminName == userName && t.Status == 0);
                    if (admin == null)
                    {
                        authFailedResponse("登录失败。用户名或密码错误");
                        return;
                    }
                    if (admin.PassWord.ToUpper() != MD5EncryptUtil.MD5Encrypt(password + admin.Salt).ToUpper())
                    {
                        authFailedResponse("登录失败。用户名或密码错误");
                        return;
                    }
                    if (!admin.UseApiDoc)
                    {
                        authFailedResponse("登录失败。账户不存在或没有权限");
                        return;
                    }

                    // 验证通过，允许访问接口文档
                    await next.Invoke(context).ConfigureAwait(false);
                    return;
                }

                // 验证失败。告知客户端需要进行 Basic 认证
                authFailedResponse("");
            }
            else
            {
                await next.Invoke(context).ConfigureAwait(false);
            }
        }
    }
}